home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / Newswatcher 2.0b22 / NW Source / Source / print.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-05  |  15.9 KB  |  692 lines  |  [TEXT/MMCC]

  1. /*----------------------------------------------------------------------------
  2.  
  3.     print.c
  4.  
  5.     This module handles printing.
  6.     
  7.     Copyright © 1994, Northwestern University.
  8.  
  9. ----------------------------------------------------------------------------*/
  10.  
  11. #include <Printing.h>
  12. #include <Script.h>
  13. #include <AppleEvents.h>
  14. #include <stdio.h>
  15. #include <string.h>
  16.  
  17. #include "glob.h"
  18. #include "print.h"
  19. #include "dialog.h"
  20. #include "memutil.h"
  21. #include "newswatcher.h"
  22. #include "dummy.h"
  23. #include "article.h"
  24. #include "strutil.h"
  25. #include "drawutil.h"
  26. #include "ic.h"
  27. #include "resutil.h"
  28.  
  29.  
  30.  
  31. #define kPageSetupInfoResourceType        'NWPS'
  32. #define kPageSetupInfoResourceID        128
  33.  
  34.  
  35.  
  36. static THPrint gMyHPrint = nil;    /* printing handle */
  37. static TEHandle gPrintTE;        /* textedit handle to print */
  38. static Handle gText;            /* text to print */
  39. static short gLinesPerPage;        /* # of lines per page */
  40. static long gNumLines;            /* total # lines */
  41. static Rect gDrawRect;            /* drawing rectangle */
  42. static short gHalfInch;            /* num pixels in 0.5 inches */
  43. static short gMyRefNum;            /* ref num of NewsWatcher's resource file */
  44.  
  45. static PrIdleUPP gIdleProcUPP = nil;
  46.  
  47. /* Globals for printing segmented article windows. */
  48.  
  49. static Boolean gSegmented;            /* true if segmented */
  50. static short gNumSections;            /* number of sections */
  51. static short gCurSection;            /* current section in gPrintTE, or -1 if none */
  52. static long **gSectionBreaks;        /* handle to array of section breaks */
  53. static long **gFirstLines;            /* handle to array of section first line numbers */
  54.  
  55.  
  56.  
  57. /*----------------------------------------------------------------------------
  58.     ReadSavedPageSetupInfoFromPrefs 
  59.     
  60.     Read the save page setup info from the NewsWatcher Prefs file.
  61. ----------------------------------------------------------------------------*/
  62.  
  63. void ReadSavedPageSetupInfoFromPrefs (void)
  64. {
  65.     OSErr err = noErr;
  66.  
  67.     err = MyGet1Resource(kPageSetupInfoResourceType, kPageSetupInfoResourceID, 
  68.         &gMyHPrint);
  69.     if (err == noErr) MyDetachResource(gMyHPrint);
  70. }
  71.  
  72.  
  73.  
  74. /*----------------------------------------------------------------------------
  75.     WritePageSetupInfoToPrefs 
  76.     
  77.     Write the page setup info to the NewsWatcher Prefs file.
  78. ----------------------------------------------------------------------------*/
  79.  
  80. void WritePageSetupInfoToPrefs (void)
  81. {
  82.     if (gMyHPrint != nil) {
  83.         MyReplaceResource(gMyHPrint, kPageSetupInfoResourceType, 
  84.             kPageSetupInfoResourceID, "\p");
  85.     }
  86. }
  87.  
  88.  
  89.  
  90. /*----------------------------------------------------------------------------
  91.     PrepSegements 
  92.     
  93.     Prepare for printing segmented article windows. Calculate the gFirstLines
  94.     array and the total number of lines.
  95. ----------------------------------------------------------------------------*/
  96.  
  97. static void PrepSegmented (void)
  98. {
  99.     long linesInSection,offset,length;
  100.     short i;
  101.     char state;
  102.  
  103.     state = MyHGetState(gText);
  104.     MyHLock(gText);
  105.     for (i = gNumSections-1; i >= 0; i--) {
  106.         offset = (*gSectionBreaks)[i];
  107.         length = (*gSectionBreaks)[i+1] - offset;
  108.         TESetText(*gText+offset,length, gPrintTE);
  109.         (*gFirstLines)[i] = (**gPrintTE).nLines;
  110.     }
  111.     MyHSetState(gText, state);
  112.     
  113.     gNumLines = 0;
  114.     for (i = 0; i < gNumSections; i++) {
  115.         linesInSection = (*gFirstLines)[i];
  116.         (*gFirstLines)[i] = gNumLines;
  117.         gNumLines += linesInSection;
  118.     }
  119.     (*gFirstLines)[gNumSections] = gNumLines;
  120.     gCurSection = 0;
  121. }
  122.  
  123.  
  124.  
  125. /*----------------------------------------------------------------------------
  126.     Prep 
  127.     
  128.     Prepare for printing. Calculate the number of lines per page and the
  129.     total number of pages.
  130.  
  131.     Exit:    function result = error code.
  132. ----------------------------------------------------------------------------*/
  133.  
  134. static OSErr Prep (void)
  135. {
  136.     short numPages;
  137.  
  138.     gLinesPerPage = (gDrawRect.bottom - gDrawRect.top) / (**gPrintTE).lineHeight;
  139.     gLinesPerPage -= 8;
  140.  
  141.     if (gSegmented) {
  142.         PrepSegmented();
  143.     } else {
  144.         gNumLines = (**gPrintTE).nLines;
  145.     }
  146.     numPages = (gNumLines + gLinesPerPage - 1) / gLinesPerPage;
  147.     
  148.     if ((**gMyHPrint).prJob.iLstPage > numPages)
  149.         (**gMyHPrint).prJob.iLstPage = numPages;
  150.     if ((**gMyHPrint).prJob.iLstPage < (**gMyHPrint).prJob.iFstPage) {
  151.         ErrorMessageNumber(kStrPrintNoPagesInRange);
  152.         return userCanceledErr;
  153.     }
  154.     return noErr;
  155. }
  156.  
  157.  
  158.  
  159. /*----------------------------------------------------------------------------
  160.     PrintOnePage 
  161.     
  162.     Print one page.
  163.     
  164.     Entry:    pageNum = page number.
  165.             title = title for page header.
  166.  
  167.     Exit:    function result = error code.
  168. ----------------------------------------------------------------------------*/
  169.  
  170. static OSErr PrintOnePage (short pageNum, char *title)
  171. {
  172.     short vCoord;
  173.     long line, lastLine, length;
  174.     long offset = 0;
  175.     long firstLineThisSection = 0;
  176.     long firstLineNextSection;
  177.     short start,next;
  178.     short i;
  179.     char *sectionStart;
  180.     char state;
  181.     short lineHeight;
  182.     Str255 str;
  183.     CStr255 fmt;
  184.     short pageNumWidth, quarterInch, refNum;
  185.     Rect r;
  186.     
  187.     state = MyHGetState(gText);
  188.     MyHLock(gText);
  189.     
  190.     TextFont((**gPrintTE).txFont);
  191.     TextSize((**gPrintTE).txSize);
  192.     TextFace(0);
  193.     TextMode(srcCopy);
  194.     
  195.     lineHeight = (**gPrintTE).lineHeight;
  196.     quarterInch = gHalfInch >> 1;
  197.     
  198.     vCoord = gDrawRect.top + lineHeight + (**gPrintTE).fontAscent;
  199.     sprintf((char*)str, "%d", pageNum);
  200.     c2pstr((char*)str);
  201.     pageNumWidth = StringWidth(str);
  202.     MoveTo(gDrawRect.right - pageNumWidth - quarterInch, vCoord);
  203.     DrawString(str);
  204.     strcpy((char*)str, title);
  205.     c2pstr((char*)str);
  206.     TruncString(gDrawRect.right - gDrawRect.left - pageNumWidth - 2*gHalfInch,
  207.         str, smTruncEnd);
  208.     MoveTo(gDrawRect.left + quarterInch, vCoord);
  209.     DrawString(str);
  210.     SetRect(&r, gDrawRect.left, gDrawRect.top + lineHeight - 4, 
  211.         gDrawRect.right - 2, gDrawRect.top + 2*lineHeight + 5);
  212.     PenPat(&qd.gray);
  213.     PenSize(2, 2);
  214.     FrameRect(&r);
  215.     PenPat(&qd.black);
  216.     PenSize(1, 1);
  217.         
  218.     line = (pageNum - 1) * gLinesPerPage;
  219.     
  220.     if (line + gLinesPerPage > gNumLines)
  221.         lastLine = gNumLines;
  222.     else
  223.         lastLine = line + gLinesPerPage;
  224.     
  225.     if (gSegmented) {
  226.         for (i = 0; i < gNumSections && line >= (*gFirstLines)[i]; i++) /* do nothing */ ;
  227.         i--;
  228.         offset = (*gSectionBreaks)[i];
  229.         sectionStart = *gText + offset;
  230.         firstLineThisSection = (*gFirstLines)[i];
  231.         firstLineNextSection = (*gFirstLines)[i+1];
  232.         if (i != gCurSection) {
  233.             length = (*gSectionBreaks)[i+1] - offset;
  234.             TESetText(sectionStart,length,gPrintTE);
  235.             gCurSection = i;
  236.         }
  237.     } else {
  238.         sectionStart = *gText;
  239.     }
  240.     
  241.     start = (**gPrintTE).lineStarts[line-firstLineThisSection];
  242.     
  243.     vCoord = gDrawRect.top + 4*lineHeight + (**gPrintTE).fontAscent;
  244.     
  245.     while (true) {
  246.         if (line-firstLineThisSection < (**gPrintTE).nLines-1)
  247.             next = (**gPrintTE).lineStarts[line+1-firstLineThisSection];
  248.         else
  249.             next = (**gPrintTE).teLength;
  250.         
  251.         MoveTo(gDrawRect.left, vCoord);
  252.         DrawText(sectionStart, start, next-start);
  253.         line++;
  254.         if (line == lastLine) break;
  255.         
  256.         start = next;
  257.         if (gSegmented && line >= firstLineNextSection) {
  258.             gCurSection++;
  259.             offset = (*gSectionBreaks)[gCurSection];
  260.             sectionStart = *gText + offset;
  261.             length = (*gSectionBreaks)[gCurSection+1] - offset;
  262.             TESetText(sectionStart, length, gPrintTE);
  263.             firstLineThisSection = firstLineNextSection;
  264.             firstLineNextSection = (*gFirstLines)[gCurSection+1];
  265.             start = 0;
  266.         }
  267.  
  268.         vCoord += lineHeight;
  269.     }
  270.     
  271.     vCoord = gDrawRect.bottom - 2*lineHeight + (**gPrintTE).fontAscent;
  272.     refNum = CurResFile();
  273.     UseResFile(gMyRefNum);
  274.     GetCString(kStrPrintedFor, fmt);
  275.     UseResFile(refNum);
  276.     sprintf((char*)str, fmt, gPrefs.emailAddress, gPrefs.fullName);
  277.     c2pstr((char*)str);
  278.     TruncString(gDrawRect.right - gDrawRect.left - 2*gHalfInch,
  279.         str, smTruncEnd);
  280.     MoveTo(gDrawRect.left + quarterInch, vCoord);
  281.     DrawString(str);
  282.     SetRect(&r, gDrawRect.left, gDrawRect.bottom - 2*lineHeight - 4, 
  283.         gDrawRect.right - 2, gDrawRect.bottom - lineHeight + 5);
  284.     PenPat(&qd.gray);
  285.     PenSize(2, 2);
  286.     FrameRect(&r);
  287.     PenPat(&qd.black);
  288.     PenSize(1, 1);
  289.  
  290.     MyHSetState(gText, state);
  291.     return noErr;
  292. }
  293.  
  294.  
  295.  
  296. /*----------------------------------------------------------------------------
  297.     IdleProc 
  298.     
  299.     The printing idle proc.
  300. ----------------------------------------------------------------------------*/
  301.  
  302. static pascal void IdleProc (void)
  303. {
  304.     OSErr err = noErr;
  305.     short refNum;
  306.  
  307.     refNum = CurResFile();
  308.     UseResFile(gMyRefNum);
  309.     err = GiveTime(true);
  310.     UseResFile(refNum);
  311.     if (err != noErr) PrSetError(iPrAbort);
  312. }
  313.  
  314.  
  315.  
  316. /*----------------------------------------------------------------------------
  317.     PrintTheDoc 
  318.     
  319.     Print the document.
  320.     
  321.     Entry:    title = title for page headers, and print job name
  322.  
  323.     Exit:    function result = error code.
  324. ----------------------------------------------------------------------------*/
  325.  
  326. static OSErr PrintTheDoc (char *title)
  327. {
  328.     short theFirst, theLast;
  329.     short nCopies;
  330.     short prDevice;
  331.     Boolean draftMode;
  332.     TPrStatus prStatus;
  333.     GrafPtr port;
  334.     OSErr err = noErr;
  335.     short i, p;
  336.     TPPrPort prPort;
  337.     Boolean prIsOpen = false;
  338.     Boolean docIsOpen = false;
  339.     Boolean pageIsOpen = false;
  340.     
  341.     MyICReadSharedPrefs(kICRealName);
  342.     MyICReadSharedPrefs(kICEmail);
  343.  
  344.     GetPort(&port);
  345.     PrOpen();
  346.     err = PrError();
  347.     if (err != noErr) goto exit;
  348.     prIsOpen = true;
  349.     
  350.     err = ShowDummyWindow();
  351.     if (err != noErr) goto exit;
  352.     c2pstr(title);
  353.     SetWTitle(FrontWindow(), (StringPtr)title);
  354.     p2cstr((StringPtr)title);
  355.  
  356.     PrValidate(gMyHPrint);
  357.     err = PrError();
  358.     if (err != noErr) goto exit;
  359.     err = Prep();
  360.     if (err != noErr) goto exit;
  361.     theFirst = (**gMyHPrint).prJob.iFstPage;
  362.     theLast = (**gMyHPrint).prJob.iLstPage;
  363.     (**gMyHPrint).prJob.iFstPage = 1;
  364.     (**gMyHPrint).prJob.iLstPage = 9999;
  365.     prDevice = ((**gMyHPrint).prStl.wDev >> 8);
  366.     draftMode = (((**gMyHPrint).prJob.bJDocLoop) & 1) == 0;
  367.     if ((draftMode) && (prDevice == 1))
  368.         nCopies = (**gMyHPrint).prJob.iCopies;
  369.     else
  370.         nCopies = 1;
  371.     prPort = PrOpenDoc(gMyHPrint, nil, nil);
  372.     err = PrError();
  373.     if (err != noErr) goto exit;
  374.     docIsOpen = true;
  375.     
  376.     HideDummyWindow();
  377.     
  378.     SetPort(&prPort->gPort);
  379.     for (i=1; i <= nCopies; i++) {
  380.         for (p = theFirst; p <= theLast; p++) {
  381.             PrOpenPage(prPort, nil);
  382.             err = PrError();
  383.             if (err != noErr) goto exit;
  384.             pageIsOpen = true;
  385.             err = PrintOnePage(p, title);
  386.             if (err != noErr) goto exit;
  387.             PrClosePage(prPort);
  388.             err = PrError();
  389.             if (err != noErr) goto exit;
  390.             pageIsOpen = false;
  391.         }
  392.     }
  393.     PrCloseDoc(prPort);
  394.     err = PrError();
  395.     if (err != noErr) goto exit;
  396.     docIsOpen = false;
  397.     
  398.     if (!draftMode) {
  399.         PrPicFile(gMyHPrint, nil, nil, nil, &prStatus);
  400.         err = PrError();
  401.         if (err != noErr) goto exit;
  402.     }
  403.  
  404.     PrClose();
  405.     err = PrError();
  406.     if (err != noErr) goto exit;
  407.     prIsOpen = false;
  408.     
  409.     (**gMyHPrint).prJob.iFstPage = theFirst;
  410.     (**gMyHPrint).prJob.iLstPage = theLast;
  411.     
  412.     SetPort(port);
  413.     return noErr;
  414.     
  415. exit:
  416.  
  417.     HideDummyWindow();
  418.     SetPort(port);
  419.     if (pageIsOpen) PrClosePage(prPort);
  420.     if (docIsOpen) PrCloseDoc(prPort);
  421.     if (prIsOpen) PrClose();
  422.     return err;
  423. }
  424.  
  425.  
  426.  
  427. /*----------------------------------------------------------------------------
  428.     InitPrint 
  429.     
  430.     Intialize printing.
  431.  
  432.     Exit:    function result = error code.
  433. ----------------------------------------------------------------------------*/
  434.  
  435. static OSErr InitPrint (void)
  436. {
  437.     OSErr err = noErr;
  438.  
  439.     if (gMyHPrint != nil) return noErr;
  440.     PrOpen();
  441.     err = PrError();
  442.     if (err != noErr) return err;
  443.     err = MyNewHandle(sizeof(TPrint), &gMyHPrint);
  444.     if (err != noErr) goto exit;
  445.     PrintDefault(gMyHPrint);
  446.     err = PrError();
  447.     if (err != noErr) goto exit;
  448.     PrClose();
  449.     return PrError();
  450.     
  451. exit:
  452.  
  453.     PrClose();
  454.     return err;
  455. }
  456.  
  457.  
  458.  
  459. /*----------------------------------------------------------------------------
  460.     PrintError 
  461.     
  462.     Handle a printing error.
  463.     
  464.     Entry:    err = error code.
  465.  
  466.     Exit:    function result = error code.
  467. ----------------------------------------------------------------------------*/
  468.  
  469. static OSErr PrintError (OSErr err)
  470. {
  471.     if (err == fnfErr) {
  472.         ErrorMessageNumber(kStrPrintNoDriver);
  473.         return userCanceledErr;
  474.     } else if (err == resNotFound) {
  475.         ErrorMessageNumber(kStrNoPrinterSelected);
  476.         return userCanceledErr;
  477.     } else {
  478.         return err;
  479.     }
  480. }
  481.  
  482.  
  483.  
  484. /*----------------------------------------------------------------------------
  485.     DoPageSetup 
  486.     
  487.     Handle the "Page Setup" command.
  488.  
  489.     Exit:    function result = error code.
  490. ----------------------------------------------------------------------------*/
  491.  
  492. OSErr DoPageSetup (void)
  493. {
  494.     OSErr err = noErr;
  495.     Boolean prIsOpen = false;
  496.     
  497.     err = InitPrint();
  498.     if (err != noErr) goto exit;
  499.     InitCursor();
  500.     PrOpen();
  501.     err = PrError();
  502.     if (err != noErr) goto exit;
  503.     prIsOpen = true;
  504.     PrValidate(gMyHPrint);
  505.     err = PrError();
  506.     if (err != noErr) goto exit;
  507.     PrepUserInteraction();
  508.     PrStlDialog(gMyHPrint);
  509.     err = PrError();
  510.     if (err != noErr) goto exit;
  511.     PrClose();
  512.     err = PrError();
  513.     if (err != noErr) goto exit;
  514.     return noErr;
  515.     
  516. exit:
  517.  
  518.     if (prIsOpen) PrClose();
  519.     return PrintError(err);
  520. }
  521.  
  522.  
  523.  
  524. /*----------------------------------------------------------------------------
  525.     StartPrint 
  526.     
  527.     Present the print job dialog.
  528.  
  529.     Exit:    function result = error code.
  530. ----------------------------------------------------------------------------*/
  531.  
  532. OSErr StartPrint (void)
  533. {
  534.     Boolean result;
  535.     GrafPtr port;
  536.     OSErr err = noErr;
  537.     Boolean prIsOpen = false;
  538.     short i;
  539.  
  540.     GetPort(&port);
  541.     gMyRefNum = CurResFile();
  542.     err = InitPrint();
  543.     if (err != noErr) goto exit;
  544.     PrOpen();
  545.     err = PrError();
  546.     if (err != noErr) goto exit;
  547.     prIsOpen = true;
  548.     PrValidate(gMyHPrint);
  549.     err = PrError();
  550.     if (err != noErr) goto exit;
  551.     InitCursor();
  552.     err = PrepUserInteraction();
  553.     if (err == noErr) {
  554.         result = PrJobDialog(gMyHPrint);
  555.         err = PrError();
  556.         if (err != noErr) goto exit;
  557.         if (!result) {
  558.             err = userCanceledErr;
  559.             goto exit;
  560.         }
  561.     } else if (err == errAENoUserInteraction) {
  562.         PrintDefault(gMyHPrint);
  563.         err = noErr;
  564.     } else {
  565.         goto exit;
  566.     }
  567.     (**gMyHPrint).prJob.pIdleProc = gIdleProcUPP;
  568.  
  569.     PrClose();
  570.     err = PrError();
  571.     if (err != noErr) goto exit;
  572.     prIsOpen = false;
  573.     
  574.     for (i = 0; i < 10; i++) {
  575.         err = GiveTime(true);
  576.         if (err != noErr) goto exit;
  577.     }
  578.     
  579.     SetPort(port);
  580.     return noErr;
  581.     
  582. exit:
  583.  
  584.     SetPort(port);
  585.     if (prIsOpen) PrClose();
  586.     return PrintError(err);
  587. }
  588.  
  589.  
  590.  
  591. /*----------------------------------------------------------------------------
  592.     PrintText 
  593.     
  594.     Print text.
  595.     
  596.     Entry:    text = handle to text to be printed.
  597.             start = offset in text of beginning of text to be printed.
  598.             end = offset in text of end of text to be printed.
  599.             title = title for page headers, and print job name
  600.  
  601.     Exit:    function result = error code.
  602. ----------------------------------------------------------------------------*/
  603.  
  604. OSErr PrintText (Handle text, long start, long end, char *title)
  605. {
  606.     Handle oldText;
  607.     OSErr err = noErr;
  608.     long len;
  609.     Boolean disposeText = false;
  610.     short fontNum, iFstPage, iLstPage;
  611.     
  612.     MyICReadSharedPrefs(kICPrinterFont);
  613.     
  614.     gText = nil;
  615.     gPrintTE = nil;
  616.     gFirstLines = nil;
  617.     gSectionBreaks = nil;
  618.     
  619.     if (!MemoryAvailable(50000L)) return memFullErr;
  620.  
  621.     err = InitPrint();
  622.     if (err != noErr) return err;
  623.     
  624.     InitCursor();
  625.     
  626.     gDrawRect = (**gMyHPrint).prInfo.rPage;
  627.     gHalfInch = (**gMyHPrint).prInfo.iHRes >> 1;
  628.     gDrawRect.left += gHalfInch;
  629.     gDrawRect.right -= gHalfInch;
  630.     
  631.     gPrintTE = TENew(&gDrawRect, &gDrawRect);
  632.     GetFontNumber(gPrefs.printingFont, &fontNum);
  633.     (**gPrintTE).txFont = fontNum;
  634.     (**gPrintTE).txSize = gPrefs.printingSize;
  635.  
  636.     len = MyGetHandleSize(text);
  637.     if (start > 0 || end < len) {
  638.         len = end - start;
  639.         err = MyNewHandle(len, &gText);
  640.         if (err != noErr) goto exit;
  641.         disposeText = true;
  642.         BlockMoveData(*text + start, *gText, len);
  643.     } else {
  644.         gText = text;
  645.     }
  646.     
  647.     if (len > 0x7fff) {
  648.         gSegmented = true;
  649.         err = MakeSections(gText, &gSectionBreaks, &gNumSections);
  650.         if (err != noErr) goto exit;
  651.         gCurSection = -1;
  652.         err = MyNewHandle(sizeof(long) * (gNumSections+1), &gFirstLines);
  653.         if (err != noErr) goto exit;
  654.     } else {
  655.         gSegmented = false;
  656.         oldText = (**gPrintTE).hText;
  657.         (**gPrintTE).hText = gText;
  658.         TECalText(gPrintTE);
  659.     }
  660.     
  661.     iFstPage = (**gMyHPrint).prJob.iFstPage;
  662.     iLstPage = (**gMyHPrint).prJob.iLstPage;
  663.     err = PrintTheDoc(title);
  664.     (**gMyHPrint).prJob.iFstPage = iFstPage;
  665.     (**gMyHPrint).prJob.iLstPage = iLstPage;
  666.     
  667. exit:
  668.  
  669.     if (disposeText) MyDisposeHandle(gText);
  670.     MyDisposeHandle(gFirstLines);
  671.     MyDisposeHandle(gSectionBreaks);
  672.     if (gPrintTE != nil) {
  673.         if (!gSegmented) (**gPrintTE).hText = oldText;
  674.         TEDispose(gPrintTE);
  675.     }
  676.     
  677.     return err;
  678. }
  679.  
  680.  
  681.  
  682. /*----------------------------------------------------------------------------
  683.     print_InitUPP
  684.     
  685.     Initialize UPPs.
  686. ----------------------------------------------------------------------------*/
  687.  
  688. void print_InitUPP (void)
  689. {
  690.     gIdleProcUPP = NewPrIdleProc(IdleProc);
  691. }
  692.